package com.zmn.oms.business.impl.serviceitem;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.price.common.constant.ItemAdditionConst;
import com.zmn.base.price.common.dto.item.ItemDRO;
import com.zmn.base.price.dubbo.interfaces.item.ItemRemoteService;
import com.zmn.common.constant.FicoConsts;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.math.MathUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.discount.OrderDiscountBService;
import com.zmn.oms.business.interfaces.operation.OrderOperationBService;
import com.zmn.oms.business.interfaces.order.OrderBService;
import com.zmn.oms.business.interfaces.orderamount.OrderAmountCalcBService;
import com.zmn.oms.business.interfaces.product.OrderProductExtendBService;
import com.zmn.oms.business.interfaces.serviceitem.OrderServiceItemBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.business.interfaces.work.OrderWorkBService;
import com.zmn.oms.common.constant.ChannelConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.TriggerAmountChangeEnum;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.orderamount.OrderAmountCalcBO;
import com.zmn.oms.model.bo.orderamount.ReCalcOrderAmountDIO;
import com.zmn.oms.model.dto.serviceitem.AddOrderServiceItemDTO;
import com.zmn.oms.model.dto.work.modify.ProductTaraiffIdDTO;
import com.zmn.oms.model.dto.work.modify.ServiceItemDetailResultDTO;
import com.zmn.oms.model.dto.work.modify.ServiceItemQueryDTO;
import com.zmn.oms.model.dto.work.modify.ServiceItemResultDTO;
import com.zmn.oms.model.entity.discount.OrderDiscount;
import com.zmn.oms.model.entity.factory.OrderFactory;
import com.zmn.oms.model.entity.operation.OrderOperation;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.product.OrderProductExtend;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItemCell;
import com.zmn.oms.model.entity.wallservitem.WallServItem;
import com.zmn.oms.model.entity.wallservitem.WallServItemQuery;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.discount.OrderDiscountService;
import com.zmn.oms.services.interfaces.factory.OrderFactoryService;
import com.zmn.oms.services.interfaces.member.OrderMemberService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.product.OrderProductExtendService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.wallservitem.WallServItemService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：订单服务项实现
 *
 * @author heciqi
 * @date 2018/12/05 17:38
 */
@Service
public class OrderServiceItemBServiceImpl implements OrderServiceItemBService {

    private Logger logger = LoggerFactory.getLogger(OrderServiceItemBServiceImpl.class);
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ItemRemoteService itemRemoteService;

    @Autowired
    private OrderServiceItemService orderServiceItemService;
    @Autowired
    private OrderProductExtendBService orderProductExtendBService;
    @Autowired
    private OrderProductExtendService orderProductExtendService;
    @Autowired
    private OrderWorkAmountBService orderWorkAmountBService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderExtendService orderExtendService;
    @Autowired
    private OrderFactoryService orderFactoryService;
    @Autowired
    private OrderDiscountService orderDiscountService;
    @Autowired
    private OrderDiscountBService orderDiscountBService;
    @Autowired
    private OrderProductService orderProductService;
    @Autowired
    private BaseCodeService baseCodeService;
    @Autowired
    private OrderWorkBService orderWorkBService;
    @Autowired
    private OrderOperationBService orderOperationBService;
    @Autowired
    private OrderAmountCalcBService orderAmountCalcBService;
    @Autowired
    private OrderMemberService orderMemberService;
    @Autowired
    private OrderWarrantyService orderWarrantyService;
    @Autowired
    @Lazy
    protected OrderBService orderBService;
    @Autowired
    private ServItemBService servItemBService;
    @Autowired
    private WallServItemService wallServItemService;

    /**
     * 工程师领单时产生服务项
     *
     * @param orderWork
     */
    @Override
    public void createServiceItemByMasterTake(OrderWork orderWork) throws OmsBaseException {
        logger.info("createServiceItemByMasterTake orderId={},productId={}", orderWork.getOrderId(), orderWork.getProductId());

        // 校验产品是否存在
        Integer productId = orderWork.getProductId();
        if (NumberUtil.isNullOrZero(productId)) {
            return;
        }

        // 订单服务项
        List<OrderProductExtend> orderProductExtendList = orderProductExtendBService.getOrderProductExtend(orderWork.getOrderId());
        //  厂商保内订单 产生远程费
        boolean supportRemoteAmount = Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)
                && Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F);
        logger.info("supportRemoteAmount={}", supportRemoteAmount);
        if (supportRemoteAmount) {
            createRemoteAmountServiceItem(orderWork, orderProductExtendList);
        }

        // 修正服务项，老数据中有为空的情况
        Integer servItemType = Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_FAULT, orderWork.getServItemType())
                ? OrderConsts.SERVICE_ITEM_TYPE_FAULT : OrderConsts.SERVICE_ITEM_TYPE_ORDER;
        orderWork.setServItemType(servItemType);

        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderWork.getOrderId());
        if (CollectionUtil.isNotNullOrEmpty(orderServiceItemList)) {
            return;
        }

        // 工程师领单时
        boolean needCreateDefalutChannelServiceItem = !Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_CLEAN)
                && ChannelConsts.CHANNEL_ID_CREATE_DEFAULT_SERVICE_ITEM.contains(orderWork.getChannelId());
        logger.info("needCreateDefalutChannelServiceItem={}", needCreateDefalutChannelServiceItem);
        if (Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_REWORK)) {
            createFreeOrderServiceItem(orderWork, orderProductExtendList);
        } else if (needCreateDefalutChannelServiceItem) {
            // 1. 非一口价订单生成默认服务项
            createDefaultOrderServiceItem(orderWork, orderProductExtendList);
        }

        // 3. 新增特殊调整下

    }

    /**
     * 修改订单时重置服务项
     *
     * @param orderWork
     */
    @Override
    public void resetServiceItemByUpdate(OrderWork orderWork) throws OmsBaseException {
        // 校验产品是否存在
        Integer productId = NumberUtil.isNullOrZero(orderWork.getProductId()) ? orderWork.getShowProductId() : orderWork.getProductId();
        if (NumberUtil.isNullOrZero(productId)) {
            return;
        }

        // 修正服务项，老数据中有为空的情况
        Integer servItemType = Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_FAULT, orderWork.getServItemType())
                ? OrderConsts.SERVICE_ITEM_TYPE_FAULT : OrderConsts.SERVICE_ITEM_TYPE_ORDER;
        orderWork.setServItemType(servItemType);

        List<OrderProduct> products = orderProductService.listOrderProductByOrderId(orderWork.getOrderId());
        OrderProduct orderProduct = products.get(0);

        // 校验是否支持一口
        boolean supportFinalPrice = false;
        ServiceItemQueryDTO checkFinalPriceDTO = ServiceItemQueryDTO.builder()
                .servItemType(orderWork.getServItemType())
                .channelId(orderWork.getChannelId())
                .cityId(orderWork.getCityId())
                .productId(productId)
                .brandId(orderProduct.getBrandId())
                .bizType(orderWork.getBizType())
                .tariffId(orderProduct.getTariffId())
                .priceStandard(GlobalConsts.YES)
                .general(GlobalConsts.YES)
                .build();
        ResponseDTO<ServiceItemResultDTO> checkFinalPriceResponse = servItemBService.getServiceItem(checkFinalPriceDTO);
        if (checkFinalPriceResponse.isSuccess() && checkFinalPriceResponse.getData() != null) {
            supportFinalPrice = true;
        }

        // 订单服务项
        List<OrderProductExtend> orderProductExtendList = orderProductExtendBService.getOrderProductExtend(orderWork.getOrderId());

        // 1 生成服务项 优先级 一口价服务项 > 清洗默认服务项
        if (Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_REWORK)) {
            createFreeOrderServiceItem(orderWork, orderProductExtendList);
        } else {
            boolean needCreateDefalutChannelServiceItem = !Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_CLEAN)
                    && ChannelConsts.CHANNEL_ID_CREATE_DEFAULT_SERVICE_ITEM.contains(orderWork.getChannelId());
            // 1.1 一口价服务项
            if (supportFinalPrice && !needCreateDefalutChannelServiceItem) {
                createFinalPriceServiceItem(orderWork, orderProductExtendList, checkFinalPriceResponse.getData());
            }
            // 1.2 清洗单生成默认服务项
            else {
                createDefaultOrderServiceItem(orderWork, orderProductExtendList);
            }

            // 3. 厂商保内订单 产生远程费
            boolean supportRemoteAmount = Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)
                    && Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F);
            if (supportRemoteAmount) {
                createRemoteAmountServiceItem(orderWork, orderProductExtendList);
            }
        }
    }

    @Override
    public Integer getDiscount(AddOrderServiceItemDTO addOrderServiceItemDTO) throws OmsBaseException {
        Long orderId = addOrderServiceItemDTO.getOrderId();
        Long proExtId = addOrderServiceItemDTO.getProExtId();

        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, addOrderServiceItemDTO.getWorkId());

        List<OrderProductExtend> orderProductExtendList = orderProductExtendService.listByOrderIdSrcMaster(orderId);

        OrderProductExtend productExtend = null;
        for (OrderProductExtend obj : orderProductExtendList) {
            if (obj.getProExtId().equals(proExtId)) {
                productExtend = obj;
                break;
            }
        }
        // 产品扩展id不存在，说明产品有变化，被删除了。
        if (productExtend == null) {
            throw new OmsBaseException("工单数据有变化，请刷新后重新操作");
        }
        long tipsTime1 = System.currentTimeMillis();

        List<OrderServiceItem> orderServiceItems = addOrderServiceItemDTO.getOrderServiceItemList();
        for (OrderServiceItem orderServiceItem : orderServiceItems) {
            orderServiceItem.setOrderId(orderId);
            orderServiceItem.setProExtId(proExtId);
            orderServiceItem.setCreater(addOrderServiceItemDTO.getOperator());

            if (orderServiceItem.getProductId() == null) {
                orderServiceItem.setProductId(Optional.ofNullable(productExtend.getProductId()).orElse(orderWork.getProductId()));
            }
            if (orderServiceItem.getProductName() == null) {
                orderServiceItem.setProductName(Optional.ofNullable(productExtend.getProductName()).orElse(productExtend.getShowProductName()));
            }
            Integer price = Optional.ofNullable(orderServiceItem.getItemPrice()).orElse(0);
            Integer number = Optional.ofNullable(orderServiceItem.getNumber()).orElse(1);
            Integer totalPrice = price * number;

            // 墙面订单处理
            if (Objects.equals(addOrderServiceItemDTO.getIsWallQuotationOrder(), GlobalConsts.YES)) {
                List<WallServItem> wallServItems = wallServItemService.listByQuery(WallServItemQuery.builder()
                        .workId(orderWork.getWorkId()).servItemId(orderServiceItem.getServItemId()).build());
                if (CollectionUtil.isNotNullOrEmpty(wallServItems)) {
                    // 最低价处理
                    WallServItem wallServItem = wallServItems.get(0);
                    if (totalPrice < wallServItem.getPriceSaleLowest()) {
                        totalPrice = wallServItem.getPriceSaleLowest();
                        logger.info("墙面订单最低价处理，servItemId:{},totalPrice:{}", orderServiceItem.getServItemId(), totalPrice);
                    }
                }
            }
            orderServiceItem.setTotalPrice(totalPrice);

            //当项目未配置时，则内部结算价 = 外部价 = 销售总额
            // 处理内部结算价
            Integer internalPrice = Optional.ofNullable(orderServiceItem.getInternalSettlementPrice()).orElse(price);
            Integer internalSettlementPrice = handleSettlementPrice(orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType(), internalPrice, price);
            orderServiceItem.setInternalSettlementPrice(internalSettlementPrice);

            boolean isYeyx = Objects.equals(GlobalConsts.PLAT_MARK_YEYX, orderWork.getPlatWork());
            boolean isSpecialChannel = Objects.equals(OrderConsts.CHANNEL_ID_TMALL_WYG, orderWork.getChannelId()) || Objects.equals(OrderConsts.CHANNEL_ID_TMALL_BUSINESS, orderWork.getChannelId());
            boolean isF = Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F);
            if ((isYeyx && isSpecialChannel && isF) || Objects.isNull(orderServiceItem.getInternalTotalPrice())) {
                orderServiceItem.setInternalTotalPrice(internalSettlementPrice * number);
            }

            Integer externalSettlementPrice = Optional.ofNullable(orderServiceItem.getExternalSettlementPrice()).orElse(price);
            orderServiceItem.setExternalSettlementPrice(externalSettlementPrice);
            if (Objects.isNull(orderServiceItem.getExternalTotalPrice())) {
                orderServiceItem.setExternalTotalPrice(externalSettlementPrice * number);
            }
        }
        long tipsTime2 = System.currentTimeMillis();
        // 处理阶梯价
        handleItemsTieredPrice(orderServiceItems);

        long tipsTime3 = System.currentTimeMillis();
        // 筛选出其他产品项的原价
        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);
        int otherOriginalAmount = orderServiceItemList.stream()
                .filter(e -> !Objects.equals(proExtId, e.getProExtId()))
                .mapToInt(OrderServiceItem::getTotalPrice).sum();

        // 是否仅上门
        boolean onlyVisit = orderServiceItems.stream().anyMatch(e -> Lists.newArrayList("上门费（选择维修优惠上门费）", "上门费").contains(e.getServItemName().trim()));
        // 订单金额
        int originalAmount = orderServiceItems.stream().mapToInt(OrderServiceItem::getTotalPrice).sum();

        // 如果原价大于30 则设置为工程师收款金额
        int totalOriginalAmount = originalAmount + otherOriginalAmount;

        if (totalOriginalAmount > 3000) {
            onlyVisit = false;
        }


        long tipsTime4 = System.currentTimeMillis();
        // 计算和更新工单金额
        ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(orderWork);
        calcOrderAmountDIO.setNewOriginalAmount(totalOriginalAmount);
        calcOrderAmountDIO.setOnlyVisit(onlyVisit ? GlobalConsts.YES : GlobalConsts.NO);
        OrderAmountCalcBO orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.MODIFY_ORDER_AMOUNT, calcOrderAmountDIO, null);
        long tipsTime5 = System.currentTimeMillis();
        logger.info("getDiscount 接口调用超时分析：tips01:{} tips02:{} tips03:{} tips04:{} tips05:{}", tipsTime1, tipsTime2, tipsTime3, tipsTime4, tipsTime5);
        return orderAmountCalcBO.getMasterAmount();
    }

    /**
     * 新增订单服务项
     *
     * @param addOrderServiceItemDTO
     */
    @Override
    public ResultDTO insertServiceItem(AddOrderServiceItemDTO addOrderServiceItemDTO) throws OmsBaseException {
        Long orderId = addOrderServiceItemDTO.getOrderId();
        Long proExtId = addOrderServiceItemDTO.getProExtId();

        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, addOrderServiceItemDTO.getWorkId());

        List<OrderProductExtend> orderProductExtendList = orderProductExtendService.listByOrderIdSrcMaster(orderId);

        OrderProductExtend productExtend = null;
        for (OrderProductExtend obj : orderProductExtendList) {
            if (obj.getProExtId().equals(proExtId)) {
                productExtend = obj;
                break;
            }
        }
        // 产品扩展id不存在，说明产品有变化，被删除了。
        if (productExtend == null) {
            throw new OmsBaseException("工单数据有变化，请刷新后重新操作");
        }
        long tipsTime1 = System.currentTimeMillis();

        List<OrderServiceItem> orderServiceItems = addOrderServiceItemDTO.getOrderServiceItemList();
        for (OrderServiceItem orderServiceItem : orderServiceItems) {
            orderServiceItem.setOrderId(orderId);
            orderServiceItem.setProExtId(proExtId);
            orderServiceItem.setCreater(addOrderServiceItemDTO.getOperator());

            if (orderServiceItem.getProductId() == null) {
                orderServiceItem.setProductId(Optional.ofNullable(productExtend.getProductId()).orElse(orderWork.getProductId()));
            }
            if (orderServiceItem.getProductName() == null) {
                orderServiceItem.setProductName(Optional.ofNullable(productExtend.getProductName()).orElse(productExtend.getShowProductName()));
            }
            Integer price = Optional.ofNullable(orderServiceItem.getItemPrice()).orElse(0);
            Integer number = Optional.ofNullable(orderServiceItem.getNumber()).orElse(1);
            Integer totalPrice = price * number;

            // 墙面订单处理
            if (Objects.equals(addOrderServiceItemDTO.getIsWallQuotationOrder(), GlobalConsts.YES)) {
                List<WallServItem> wallServItems = wallServItemService.listByQuery(WallServItemQuery.builder()
                        .workId(orderWork.getWorkId()).servItemId(orderServiceItem.getServItemId()).build());
                if (CollectionUtil.isNotNullOrEmpty(wallServItems)) {
                    // 最低价处理
                    WallServItem wallServItem = wallServItems.get(0);
                    if (totalPrice < wallServItem.getPriceSaleLowest()) {
                        totalPrice = wallServItem.getPriceSaleLowest();
                        logger.info("墙面订单最低价处理，servItemId:{},totalPrice:{}", orderServiceItem.getServItemId(), totalPrice);
                    }
                }
            }
            orderServiceItem.setTotalPrice(totalPrice);

            //当项目未配置时，则内部结算价 = 外部价 = 销售总额
            // 处理内部结算价
            Integer internalPrice = Optional.ofNullable(orderServiceItem.getInternalSettlementPrice()).orElse(price);
            Integer internalSettlementPrice = handleSettlementPrice(orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType(), internalPrice, price);
            orderServiceItem.setInternalSettlementPrice(internalSettlementPrice);

            boolean isYeyx = Objects.equals(GlobalConsts.PLAT_MARK_YEYX, orderWork.getPlatWork());
            boolean isSpecialChannel = Objects.equals(OrderConsts.CHANNEL_ID_TMALL_WYG, orderWork.getChannelId()) || Objects.equals(OrderConsts.CHANNEL_ID_TMALL_BUSINESS, orderWork.getChannelId());
            boolean isF = Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F);
            if ((isYeyx && isSpecialChannel && isF) || Objects.isNull(orderServiceItem.getInternalTotalPrice())) {
                orderServiceItem.setInternalTotalPrice(internalSettlementPrice * number);
            }

            Integer externalSettlementPrice = Optional.ofNullable(orderServiceItem.getExternalSettlementPrice()).orElse(price);
            orderServiceItem.setExternalSettlementPrice(externalSettlementPrice);
            if (Objects.isNull(orderServiceItem.getExternalTotalPrice())) {
                orderServiceItem.setExternalTotalPrice(externalSettlementPrice * number);
            }
        }
        long tipsTime2 = System.currentTimeMillis();
        // 处理阶梯价
        handleItemsTieredPrice(orderServiceItems);

        orderServiceItemService.deleteByProExtId(proExtId);

        // 新增时校验非空再新增
        if (!CollectionUtils.isEmpty(orderServiceItems)) {
            orderServiceItemService.insertAll(orderServiceItems);

            //保存报价人信息
            OrderOperation orderOperation = new OrderOperation();
            orderOperation.setOrderId(addOrderServiceItemDTO.getOrderId());
            orderOperation.setQuotationId(addOrderServiceItemDTO.getOperatorId() == null ? 0L : addOrderServiceItemDTO.getOperatorId());
            orderOperation.setQuotationType(addOrderServiceItemDTO.getQuotationType() == null ?
                    GlobalConsts.OPERATE_USER_TYPE_SYSTEM : addOrderServiceItemDTO.getQuotationType());
            orderOperation.setQuotationName(addOrderServiceItemDTO.getOperator() == null ? "系统" : addOrderServiceItemDTO.getOperator());
            orderOperation.setCreater(addOrderServiceItemDTO.getOperator() == null ? "系统" : addOrderServiceItemDTO.getOperator());
            Date currentTime = DateUtil.getNow();
            orderOperation.setQuotationTime(currentTime);
            orderOperation.setCreateTime(currentTime);
            orderOperationBService.insertOrUpdateByKey(orderOperation);
        }
        long tipsTime3 = System.currentTimeMillis();
        // 筛选出其他产品项的原价
        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);
        int otherOriginalAmount = orderServiceItemList.stream()
                .filter(e -> !Objects.equals(proExtId, e.getProExtId()))
                .mapToInt(OrderServiceItem::getTotalPrice).sum();

        // 是否仅上门
        boolean onlyVisit = orderServiceItems.stream().anyMatch(e -> Lists.newArrayList("上门费（选择维修优惠上门费）", "上门费").contains(e.getServItemName().trim()));
        // 订单金额
        int originalAmount = orderServiceItems.stream().mapToInt(OrderServiceItem::getTotalPrice).sum();

        // 如果原价大于30 则设置为工程师收款金额
        int totalOriginalAmount = originalAmount + otherOriginalAmount;

        if (totalOriginalAmount > 3000) {
            onlyVisit = false;
        }

        // 所有扩展产品都选择了服务项再计算原价
        Set<Long> proExtSet = orderServiceItemList.stream().map(e -> e.getProExtId()).collect(Collectors.toSet());
        if (!Objects.equals(proExtSet.size(), orderProductExtendList.size())) {
            return ResultDTO.success();
        }
        long tipsTime4 = System.currentTimeMillis();
        // 计算和更新工单金额
        ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(orderWork);
        calcOrderAmountDIO.setNewOriginalAmount(totalOriginalAmount);
        calcOrderAmountDIO.setOnlyVisit(onlyVisit ? GlobalConsts.YES : GlobalConsts.NO);
        OrderAmountCalcBO orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.MODIFY_ORDER_AMOUNT, calcOrderAmountDIO, null);
        orderWorkAmountBService.updateAmountAndDiscount(orderAmountCalcBO, orderWork);
        long tipsTime5 = System.currentTimeMillis();
        // 清空保修项
        orderWarrantyService.deleteByOrderId(orderId);

/*        Integer masterPayStatus = orderWork.getMasterPayStatus();
        if (Objects.equals(masterPayStatus, GlobalConsts.PAY_STATUS_DONE)) {
            // 订单已支付的走修改渠道预收流程
            WorkUpdateAmountDTO updateAmountDTO = new WorkUpdateAmountDTO();
            updateAmountDTO.setOrderId(orderId);
            updateAmountDTO.setWorkId(orderId);
            updateAmountDTO.setOriginalAmount(totalOriginalAmount);
            orderWorkAmountBService.updateOriginalAmountAfterPayment(updateAmountDTO, orderWork);
        } else {

            // 向渠道结算的订单，不需要我们向客户收费，如果渠道预付款小于订单金额，差额使用渠道优惠补齐
            *//**
         if (orderWork.getChannelPrepayAmount() != null) {
         processOrderDiscountOnChannelPrepayOnly(orderId, totalOriginalAmount, orderWork.getChannelPrepayAmount());
         }
         *//*

            // 订单未支付走修改工程师收款流程
            WorkUpdateAmountDTO updateAmountDTO = new WorkUpdateAmountDTO();
            updateAmountDTO.setOrderId(orderId);
            updateAmountDTO.setWorkId(orderId);
            updateAmountDTO.setOriginalAmount(totalOriginalAmount);
            updateAmountDTO.setOnlyVisit(onlyVisit ? GlobalConsts.YES : GlobalConsts.NO);
            updateAmountDTO.setEqutityId(addOrderServiceItemDTO.getEquityId());
            updateAmountDTO.setIsProductChanged(addOrderServiceItemDTO.getIsProductChanged());
            orderWorkAmountBService.updateOriginalAmount(updateAmountDTO);

            // 处理订单人工优惠 优惠金额高于六折 则删除人工优惠
            processOrderOperateDiscount(updateAmountDTO);

            // 自动使用用户优惠券
            return processOrderCoupon(orderWork, addOrderServiceItemDTO);
        }*/
        // 处理价格表id
        List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(orderId);
        OrderProductExtend finalProductExtend = productExtend;
        OrderProduct orderProduct = orderProducts.stream()
                .filter(e -> Objects.equals(e.getProductId(), finalProductExtend.getProductId()))
                .findFirst()
                .orElse(null);
        if (Objects.nonNull(orderProduct)) {
            List<OrderProduct> orderProductList = Lists.newArrayList(orderProduct);
            ProductTaraiffIdDTO productTaraiffIdDTO = ProductTaraiffIdDTO
                    .builder()
                    .channelId(orderWork.getChannelId())
                    .cityId(orderWork.getCityId())
                    .bizType(orderWork.getBizType())
                    .orderProductList(orderProductList)
                    .tariffType(addOrderServiceItemDTO.getTariffType())
                    .build();
            servItemBService.processProductTaraiffId(productTaraiffIdDTO);
            orderProductService.updateTariffIdByKey(orderProductList.get(0));
        }
        logger.info("insertServiceItem 接口调用超时分析：tips01:{} tips02:{} tips03:{} tips04:{} tips05:{}", tipsTime1, tipsTime2, tipsTime3, tipsTime4, tipsTime5);
        return ResultDTO.success();
    }

    /**
     * 删除订单服务项
     *
     * @param orderId
     */
    @Override
    public void deleteServiceItemByOrderId(Long orderId) {
        // 删产品扩展表
        orderProductExtendService.deleteByOrderId(orderId);
        // 删订单服务项
        orderServiceItemService.deleteByOrderId(orderId);
    }

    /**
     * 获取原价
     *
     * @param orderWork
     * @param orderProduct
     */
    @Override
    public Integer getServiceItemOriginalAmount(OrderWork orderWork, OrderProduct orderProduct) {

        // 1. 清洗单，保外原价
        if (Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_CLEAN) && Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_C)) {
            return getCleanOrderServiceItemOriginalAmount(orderWork, orderProduct);
        }

        // 2. 天猫无忧购渠道 & 天猫B端安装 & 安装服务分类 订单金额
        Integer channelId = orderWork.getChannelId();
        if (Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_INSTALL)) {
            if (Objects.equals(OrderConsts.CHANNEL_ID_TMALL_WYG, channelId)
                    || Objects.equals(OrderConsts.CHANNEL_ID_TMALL_BIZ_OPPEIN, channelId)
                    || Objects.equals(OrderConsts.CHANNEL_ID_TMALL_BIZ_LAIMD, channelId)
                    || Objects.equals(OrderConsts.CHANNEL_ID_TMALL_BUSINESS, channelId)) {
                return getTmallInstallServiceItemOriginalAmount(orderWork, orderProduct);
            }
        }

        // 3. 厂商保内清洗订单 产生远程费
        boolean supportRemoteAmount = Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_CLEAN)
                && Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)
                && Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F);
        if (supportRemoteAmount) {
            return getRemoteAmountServiceItemOriginalAmount(orderWork, orderProduct);
        }

        return null;
    }

    /**
     * 删除和创建新的费用服务项
     *
     * @return
     */
    @Override
    public void deleteAndCreateFreeServiceItem(OrderWork orderWork, List<OrderProductExtend> orderProductExtendList, Integer amount) {
        if (CollectionUtil.isNullOrEmpty(orderProductExtendList)) {
            return;
        }
        Long orderId = orderProductExtendList.get(0).getOrderId();

        // 获取费用服务项
        List<OrderServiceItem> freeServiceItem = listFreeServiceItemByAmount(orderWork, orderProductExtendList, amount);// 其他默认服务器
        if (CollectionUtils.isEmpty(freeServiceItem)) {
            return;
        }
        // 删除服务项
        orderServiceItemService.deleteByOrderId(orderId);
        // 新增服务项
        orderServiceItemService.insertAll(freeServiceItem);
    }

    /**
     * 处理内部结算价
     */
    @Override
    public Integer handleSettlementPrice(Integer platWork, Integer channelId, Integer bizType,
                                         Integer settlementPrice, Integer price) {
        /*
         * 1、服务平台：言而有信；
         * 2、渠道ID：10133、31055；
         * 3、订单业务类型：F订单；
         * 调整点：
         * 1、内部价变更=销售价X80%；
         * 2、四舍五入，单位取到：分；
         */
        boolean isYeyx = Objects.equals(GlobalConsts.PLAT_MARK_YEYX, platWork);
        boolean isSpecialChannel = Objects.equals(OrderConsts.CHANNEL_ID_TMALL_WYG, channelId) || Objects.equals(OrderConsts.CHANNEL_ID_TMALL_BUSINESS, channelId);
        boolean isF = Objects.equals(bizType, com.zmn.consts.GlobalConsts.BIZ_TYPE_F);

        // 分四舍五入取80%
        if (isYeyx && isSpecialChannel && isF) {

            if (NumberUtil.isNullOrZero(price)) {
                return price;
            }

            return (int) Math.round(price * 0.8);
        }

        return settlementPrice;
    }

    /**
     * 阶梯价格处理
     */
    @Override
    public void handleItemsTieredPrice(List<OrderServiceItem> serviceItems) {
        if (CollectionUtil.isNullOrEmpty(serviceItems)) {
            return;
        }
        // 是否存在阶梯价格
        Integer tieredTotalPrice = serviceItems.stream().filter(e -> e.getTieredTotalPrice() != null).mapToInt(OrderServiceItem::getTieredTotalPrice).sum();
        if (NumberUtil.isNullOrZero(tieredTotalPrice)) {
            return;
        }
        for (OrderServiceItem serviceItem : serviceItems) {
            if (NumberUtil.isNotNullOrZero(serviceItem.getTieredTotalPrice())) {
                serviceItem.setOrigItemPrice(serviceItem.getItemPrice());
                serviceItem.setOrigTotalPrice(serviceItem.getItemPrice() * serviceItem.getNumber());
                serviceItem.setTotalPrice(serviceItem.getTieredTotalPrice());
                serviceItem.setItemPrice(0);
            }
        }
    }

    /**
     * 新增特殊调整项
     *
     * @return
     */
    private void createSpecialServiceItem(OrderWork orderWork, List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {
        // 获取默认服务项
        List<OrderServiceItem> freeServiceItem = listFreeServiceItem(orderWork, orderProductExtendList);// 其他默认服务器
        if (CollectionUtils.isEmpty(freeServiceItem)) {
            return;
        }

        logger.debug("[{}]工单默认服务项[{}]", orderWork.getWorkId(), freeServiceItem);
        // 会员单，获取会员权益ID
        Integer equityId = null;
        boolean isMemberOrder = orderWork.getMember() != null && Objects.equals(orderWork.getMember(), GlobalConsts.YES);
        if (isMemberOrder) {
            List<OrderDiscount> equityList = orderDiscountService.listByOrderIdAndCateg(orderWork.getOrderId(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_MEMBER);
            if (!CollectionUtils.isEmpty(equityList)) {
                OrderDiscount orderDiscount = equityList.get(0);
                equityId = orderDiscount.getSourceId();
            }
        }

        // 服务项新增
        for (OrderServiceItem orderServiceItem : freeServiceItem) {
            AddOrderServiceItemDTO serviceItemDTO = new AddOrderServiceItemDTO();
            serviceItemDTO.setProExtId(orderServiceItem.getProExtId());
            serviceItemDTO.setOrderServiceItemList(Lists.newArrayList(orderServiceItem));
            serviceItemDTO.setOrderId(orderWork.getOrderId());
            serviceItemDTO.setWorkId(orderWork.getWorkId());
            serviceItemDTO.setEquityId(equityId);
            insertServiceItem(serviceItemDTO);// 新增
        }
    }


    /* **************************************************/
    /* ***************** Private Method *****************/
    /* **************************************************/

    /**
     * 生成默认服务项
     *
     * @return
     */
    private void createDefaultOrderServiceItem(OrderWork orderWork, List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {
        // 获取默认服务项
        List<OrderServiceItem> defalutServiceItem = Lists.newArrayList();

        boolean needCreateDefalutChannelServiceItem = !Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_CLEAN)
                && ChannelConsts.CHANNEL_ID_CREATE_DEFAULT_SERVICE_ITEM.contains(orderWork.getChannelId());
        logger.info("needCreateDefalutChannelServiceItem={}", needCreateDefalutChannelServiceItem);
        if (needCreateDefalutChannelServiceItem) {
            defalutServiceItem = listChannelDefalutServiceItem(orderWork, orderProductExtendList);// 渠道默认服务项
        } else {
            List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderWork.getOrderId());
            if (!CollectionUtils.isEmpty(orderServiceItemList)) {
                return;
            }
            defalutServiceItem = listDefalutServiceItem(orderWork, orderProductExtendList);// 其他默认服务器
        }
        if (CollectionUtils.isEmpty(defalutServiceItem)) {
            return;
        }

        logger.debug("[{}]工单默认服务项[{}]", orderWork.getWorkId(), defalutServiceItem);
        // 会员单，获取会员权益ID
        Integer equityId = null;
        boolean isMemberOrder = orderWork.getMember() != null && Objects.equals(orderWork.getMember(), GlobalConsts.YES);
        if (isMemberOrder) {
            List<OrderDiscount> equityList = orderDiscountService.listByOrderIdAndCateg(orderWork.getOrderId(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_MEMBER);
            if (!CollectionUtils.isEmpty(equityList)) {
                OrderDiscount orderDiscount = equityList.get(0);
                equityId = orderDiscount.getSourceId();
            }
        }

        // 服务项新增
        for (OrderServiceItem orderServiceItem : defalutServiceItem) {
            AddOrderServiceItemDTO serviceItemDTO = new AddOrderServiceItemDTO();
            serviceItemDTO.setProExtId(orderServiceItem.getProExtId());
            serviceItemDTO.setOrderServiceItemList(Lists.newArrayList(orderServiceItem));
            serviceItemDTO.setOrderId(orderWork.getOrderId());
            serviceItemDTO.setWorkId(orderWork.getWorkId());
            serviceItemDTO.setEquityId(equityId);
            insertServiceItem(serviceItemDTO);// 新增
        }
    }

    /**
     * 生成免费服务项
     *
     * @return
     */
    private void createFreeOrderServiceItem(OrderWork orderWork, List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {
        // 获取默认服务项
        List<OrderServiceItem> freeServiceItem = listFreeServiceItem(orderWork, orderProductExtendList);// 其他默认服务器
        if (CollectionUtils.isEmpty(freeServiceItem)) {
            return;
        }

        logger.debug("[{}]工单默认服务项[{}]", orderWork.getWorkId(), freeServiceItem);
        // 会员单，获取会员权益ID
        Integer equityId = null;
        boolean isMemberOrder = orderWork.getMember() != null && Objects.equals(orderWork.getMember(), GlobalConsts.YES);
        if (isMemberOrder) {
            List<OrderDiscount> equityList = orderDiscountService.listByOrderIdAndCateg(orderWork.getOrderId(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_MEMBER);
            if (!CollectionUtils.isEmpty(equityList)) {
                OrderDiscount orderDiscount = equityList.get(0);
                equityId = orderDiscount.getSourceId();
            }
        }

        // 服务项新增
        for (OrderServiceItem orderServiceItem : freeServiceItem) {
            AddOrderServiceItemDTO serviceItemDTO = new AddOrderServiceItemDTO();
            serviceItemDTO.setProExtId(orderServiceItem.getProExtId());
            serviceItemDTO.setOrderServiceItemList(Lists.newArrayList(orderServiceItem));
            serviceItemDTO.setOrderId(orderWork.getOrderId());
            serviceItemDTO.setWorkId(orderWork.getWorkId());
            serviceItemDTO.setEquityId(equityId);
            insertServiceItem(serviceItemDTO);// 新增
        }
    }

    /**
     * 远程费服务项目
     *
     * @param orderWork
     * @param orderProductExtendList
     */
    private void createRemoteAmountServiceItem(OrderWork orderWork, List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {

        Long orderId = orderWork.getOrderId();

        // 厂商订单 不存在
        OrderFactory orderFactory = orderFactoryService.findOrderFactoryByKey(orderId);
        if (orderFactory == null) {
            logger.error("#order#serviceitem 厂商订单不存在 订单号：{}", orderId);
            return;
        }

        // 远程费为空
        Integer remoteAmount = orderFactory.getRemoteAmount();
        if (NumberUtil.isNullOrZero(remoteAmount)) {
            logger.error("#order#serviceitem 厂商订单远程费未计算为空 订单号：{}", orderId);
            return;
        }

        // 远程费放在第一个产品下
        OrderProductExtend orderProductExtend = orderProductExtendList.get(0);
        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);

        // 远程服务项
        OrderServiceItem remoteAmountServiceItem = getRemoteAmountServiceItem(orderWork, remoteAmount, orderProductExtend.getProExtId(), orderProductExtend.getProductId(), orderProductExtend.getProductName());
        if (remoteAmountServiceItem == null) {
            logger.error("#order#serviceitem 远程费服务项为空 订单号：{}", orderId);
            return;
        }

        Integer serviceItemId = remoteAmountServiceItem.getServItemId();

        // 服务项不为空
        if (!CollectionUtils.isEmpty(orderServiceItemList)) {

            //  并且有其他服务项 正常计算原价 应收 。。。
            if (orderServiceItemList.stream().anyMatch(e -> !Objects.equals(e.getItemId(), serviceItemId))) {

                // 过滤出 第一个产品 非远程费的服务项
                List<OrderServiceItem> serviceItemList = orderServiceItemList.stream()
                        .filter(e -> Objects.equals(e.getProExtId(), orderProductExtend.getProExtId()) && !Objects.equals(e.getItemId(), serviceItemId))
                        .collect(Collectors.toList());

                // 远程费金额 > 0 添加远程费服务项
                if (remoteAmountServiceItem.getItemPrice() > 0) {
                    serviceItemList.add(remoteAmountServiceItem);
                }

                // 正常计算原价 应收 。。。
                AddOrderServiceItemDTO serviceItemDTO = new AddOrderServiceItemDTO();
                serviceItemDTO.setProExtId(orderProductExtend.getProExtId());
                serviceItemDTO.setOrderServiceItemList(serviceItemList);
                serviceItemDTO.setOrderId(orderWork.getOrderId());
                serviceItemDTO.setWorkId(orderWork.getWorkId());
                insertServiceItem(serviceItemDTO);

                // 只有远程费服务项 先删后增
            } else {
                orderServiceItemService.deleteByOrderIdAndServiceItemId(orderId, serviceItemId);
                if (remoteAmountServiceItem.getItemPrice() > 0) {
                    orderServiceItemService.insertAll(Lists.newArrayList(remoteAmountServiceItem));
                }
            }

            // 订单服务项为空时 只需新增一条服务项
        } else {
            orderServiceItemService.insertAll(Lists.newArrayList(remoteAmountServiceItem));
        }
    }

    /**
     * 获取默认服务项
     *
     * @param orderWork
     * @param orderProductExtendList
     */
    private List<OrderServiceItem> listDefalutServiceItem(OrderWork orderWork,
                                                          List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {
        if (servItemBService.isQuotationType(orderWork.getServItemType())) {
            return listDefaultServiceItem4Quotation(orderWork, orderProductExtendList);
        } else {
            return listDefaultServiceItem4Normal(orderWork, orderProductExtendList);
        }
    }

    /**
     * 获取计价器默认故障服务项
     *
     * @param orderWork
     * @param orderProductExtendList
     * @return
     * @throws OmsBaseException
     */
    private List<OrderServiceItem> listDefaultServiceItem4Quotation(OrderWork orderWork,
                                                                    List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {
        List<OrderServiceItem> defaultServiceItemLists = Lists.newArrayList();

        List<OrderProduct> products = orderProductService.listOrderProductByOrderId(orderWork.getOrderId());
        OrderProduct orderProduct = products.get(0);

        // 没有后台产品ID
        if (NumberUtil.isNullOrZero(orderProduct.getProductId())) {
            logger.error("#order#serviceitem 没有后台产品ID！orderId=[{}], showProductID=[{}]",
                    orderWork.getOrderId(), orderProduct.getShowProductId());
            return defaultServiceItemLists;
        }

        ServiceItemQueryDTO build = ServiceItemQueryDTO
                .builder()
                .servItemType(orderWork.getServItemType())
                .channelId(orderWork.getChannelId())
                .cityId(orderWork.getCityId())
                .productId(orderWork.getProductId())
                .brandId(orderProduct.getBrandId())
                .bizType(orderWork.getBizType())
                .general(GlobalConsts.YES)
                .tariffId(orderProduct.getTariffId())
                .build();
        ResponseDTO<ServiceItemResultDTO> faultItemResponse = servItemBService.getServiceItem(build);

        if (!faultItemResponse.isSuccess() || Objects.isNull(faultItemResponse.getData())) {
            return defaultServiceItemLists;
        }

        ServiceItemResultDTO defaultFaultItemDRO = faultItemResponse.getData();
        for (OrderProductExtend e : orderProductExtendList) {

            Integer internalPrice = Optional.ofNullable(defaultFaultItemDRO.getInternalSettlementPrice()).orElse(defaultFaultItemDRO.getPrice());
            Integer internalSettlementPrice = handleSettlementPrice(orderWork.getPlat(), orderWork.getChannelId(), orderWork.getBizType(), internalPrice, defaultFaultItemDRO.getPrice());
            OrderServiceItem orderServiceItem = new OrderServiceItem();
            orderServiceItem.setOrderId(orderWork.getOrderId());
            orderServiceItem.setProExtId(e.getProExtId());
            orderServiceItem.setProductId(orderWork.getProductId());
            orderServiceItem.setProductName(Optional.ofNullable(e.getProductName()).orElse(e.getShowProductName()));
            orderServiceItem.setServItemId(defaultFaultItemDRO.getItemId());
            orderServiceItem.setServItemName(defaultFaultItemDRO.getItemName());
            orderServiceItem.setServItemGroupId(defaultFaultItemDRO.getItemCategId());
            orderServiceItem.setServItemGroupName(defaultFaultItemDRO.getItemCategName());
            orderServiceItem.setServItemCategId(defaultFaultItemDRO.getItemCategId());
            orderServiceItem.setNumber(1);
            orderServiceItem.setItemPrice(defaultFaultItemDRO.getPrice());
            orderServiceItem.setTotalPrice(defaultFaultItemDRO.getPrice());
            orderServiceItem.setExternalSettlementPrice(defaultFaultItemDRO.getExternalSettlementPrice());
            orderServiceItem.setExternalTotalPrice(defaultFaultItemDRO.getExternalSettlementPrice());
            orderServiceItem.setInternalSettlementPrice(internalSettlementPrice);
            orderServiceItem.setInternalTotalPrice(internalSettlementPrice);

            if (CollectionUtil.isNotNullOrEmpty(defaultFaultItemDRO.getDetailResultDTOList())) {
                List<OrderServiceItemCell> itemCellList = new ArrayList<>(defaultFaultItemDRO.getDetailResultDTOList().size());
                for (ServiceItemDetailResultDTO itemCell : defaultFaultItemDRO.getDetailResultDTOList()) {
                    OrderServiceItemCell cell = new OrderServiceItemCell();
                    cell.setItemCellId(itemCell.getItemCellId());
                    cell.setItemCellName(itemCell.getItemCellName());
                    cell.setCellPrice(itemCell.getCellPrice());
                    cell.setSort(itemCell.getSort());
                    itemCellList.add(cell);
                }
                orderServiceItem.setItemDetailList(itemCellList);
            }

            defaultServiceItemLists.add(orderServiceItem);
        }
        return defaultServiceItemLists;
    }

    /**
     * @param orderWork
     * @param orderProductExtendList
     * @return
     * @throws OmsBaseException
     */
    private List<OrderServiceItem> listDefaultServiceItem4Normal(OrderWork orderWork, List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {
        List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(orderWork.getOrderId());
        Integer usableProductId = NumberUtil.isNullOrZero(orderWork.getProductId()) ? orderWork.getShowProductId() : orderWork.getProductId();

        List<OrderServiceItem> defaultServiceItemLists = Lists.newArrayList();

        ServiceItemQueryDTO build = ServiceItemQueryDTO
                .builder()
                .servItemType(orderWork.getServItemType())
                .channelId(orderWork.getChannelId())
                .cityId(orderWork.getCityId())
                .productId(usableProductId)
                .brandId(orderProducts.get(0).getBrandId())
                .bizType(orderWork.getBizType())
                .general(GlobalConsts.YES)
                .tariffId(orderProducts.get(0).getTariffId())
                .build();
        ResponseDTO<ServiceItemResultDTO> faultItemResponse = servItemBService.getServiceItem(build);

        if (!faultItemResponse.isSuccess() || Objects.isNull(faultItemResponse.getData())) {
            return defaultServiceItemLists;
        }


        ServiceItemResultDTO itemDRO = faultItemResponse.getData();
        for (OrderProductExtend e : orderProductExtendList) {
            // 处理内部结算价
            Integer internalPrice = Optional.ofNullable(itemDRO.getInternalSettlementPrice()).orElse(itemDRO.getPrice());
            Integer internalSettlementPrice = handleSettlementPrice(orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType(), internalPrice, itemDRO.getPrice());

            OrderServiceItem orderServiceItem = new OrderServiceItem();
            orderServiceItem.setOrderId(orderWork.getOrderId());
            orderServiceItem.setProExtId(e.getProExtId());
            orderServiceItem.setProductId(orderWork.getProductId());
            orderServiceItem.setProductName(Optional.ofNullable(e.getProductName()).orElse(e.getShowProductName()));
            orderServiceItem.setServItemId(itemDRO.getItemId());
            orderServiceItem.setServItemName(itemDRO.getItemName());
            orderServiceItem.setServItemGroupId(itemDRO.getItemCategId());
            orderServiceItem.setServItemGroupName(itemDRO.getItemCategName());
            orderServiceItem.setServItemCategId(itemDRO.getItemCategId());
            orderServiceItem.setNumber(1);
            orderServiceItem.setItemPrice(itemDRO.getPrice());
            orderServiceItem.setTotalPrice(itemDRO.getPrice());
            orderServiceItem.setExternalSettlementPrice(Optional.ofNullable(itemDRO.getExternalSettlementPrice()).orElse(itemDRO.getPrice()));
            orderServiceItem.setExternalTotalPrice(Optional.ofNullable(itemDRO.getExternalSettlementPrice()).orElse(itemDRO.getPrice()));
            orderServiceItem.setInternalSettlementPrice(internalSettlementPrice);
            orderServiceItem.setInternalTotalPrice(internalSettlementPrice);
            defaultServiceItemLists.add(orderServiceItem);
        }

        return defaultServiceItemLists;
    }

    /**
     * 获取渠道默认服务项
     *
     * @param orderWork
     * @param orderProductExtendList
     */
    private List<OrderServiceItem> listChannelDefalutServiceItem(OrderWork orderWork,
                                                                 List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {
        Long orderId = orderWork.getOrderId();
        Integer channelPrepayAmount = orderWork.getChannelPrepayAmount();
        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);

        List<OrderServiceItem> defaultOrderServiceItemLists = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(orderServiceItemList)) {
            logger.error("#order#serviceitem 有服务项不生成默认服务项，订单号：{}", orderId);
            return defaultOrderServiceItemLists;
        }

        if (NumberUtil.isNullOrZero(channelPrepayAmount)) {
            logger.error("#order#serviceitem 渠道预付不存在，订单号：{}", orderId);
            return defaultOrderServiceItemLists;
        }
        return this.listFreeServiceItemByAmount(orderWork, orderProductExtendList, channelPrepayAmount);
    }

    /**
     * 根据金额返回对应的特殊服务项
     *
     * @param orderProductExtendList
     * @param amount
     * @return
     */
    private List<OrderServiceItem> listFreeServiceItemByAmount(OrderWork orderWork, List<OrderProductExtend> orderProductExtendList, Integer amount) {
        List<OrderServiceItem> defaultOrderServiceItemLists = Lists.newArrayList();
        if (CollectionUtil.isNullOrEmpty(orderProductExtendList)) {
            return defaultOrderServiceItemLists;
        }
        logger.info("itemRemoteService.listSpecialItemByIdList idList={}", ItemAdditionConst.ADDITION_FREE);
        ResponseDTO<List<ItemDRO>> itemResponseDTO = itemRemoteService.listSpecialItemByIdList(Lists.newArrayList(ItemAdditionConst.ADDITION_FREE));
        logger.info("itemRemoteService.listSpecialItemByIdList itemResponseDTO={}", itemResponseDTO);
        if (!itemResponseDTO.isSuccess()) {
            logger.error("#order#listFreeServiceItemByAmount 无服务项 categid ：{} ", ItemAdditionConst.ADDITION_FREE);
            return defaultOrderServiceItemLists;
        }
        if (CollectionUtils.isEmpty(itemResponseDTO.getData())) {
            logger.error("#order#listFreeServiceItemByAmount 无服务项 categid ：{} ", ItemAdditionConst.ADDITION_FREE);
            return defaultOrderServiceItemLists;
        }

        // 多个产品，每个服务项价格平均分类
        int serviceItemAmount = (int) MathUtil.div(amount, orderProductExtendList.size(), 2);
        ItemDRO defaultServiceItemDRO = itemResponseDTO.getData().get(0);
        for (OrderProductExtend e : orderProductExtendList) {
            Integer internalPrice = Optional.ofNullable(defaultServiceItemDRO.getPriceInternalSettlement()).orElse(serviceItemAmount);
            Integer internalSettlementPrice = handleSettlementPrice(orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType(), internalPrice, serviceItemAmount);

            OrderServiceItem orderServiceItem = new OrderServiceItem();
            orderServiceItem.setOrderId(e.getOrderId());
            orderServiceItem.setProExtId(e.getProExtId());
            orderServiceItem.setProductId(e.getProductId());
            orderServiceItem.setProductName(Optional.ofNullable(e.getProductName()).orElse(e.getShowProductName()));
            orderServiceItem.setServItemId(defaultServiceItemDRO.getItemId());
            orderServiceItem.setServItemName(defaultServiceItemDRO.getItemName());
            orderServiceItem.setServItemCategId(defaultServiceItemDRO.getItemTypeId());
            orderServiceItem.setServItemGroupId(defaultServiceItemDRO.getItemTypeId());
            orderServiceItem.setServItemGroupName(defaultServiceItemDRO.getItemTypeName());
            orderServiceItem.setNumber(1);
            orderServiceItem.setItemPrice(serviceItemAmount);
            orderServiceItem.setTotalPrice(serviceItemAmount);

            orderServiceItem.setExternalSettlementPrice(defaultServiceItemDRO.getPriceExternalSettlement());
            orderServiceItem.setExternalTotalPrice(defaultServiceItemDRO.getPriceExternalSettlement());
            orderServiceItem.setInternalSettlementPrice(internalSettlementPrice);
            orderServiceItem.setInternalTotalPrice(internalSettlementPrice);

            defaultOrderServiceItemLists.add(orderServiceItem);
        }
        return defaultOrderServiceItemLists;
    }

    /**
     * 获取免费默认服务项
     *
     * @param orderWork
     * @param orderProductExtendList
     */
    private List<OrderServiceItem> listFreeServiceItem(OrderWork orderWork,
                                                       List<OrderProductExtend> orderProductExtendList) throws OmsBaseException {
        List<OrderServiceItem> freeOrderServiceItemLists = Lists.newArrayList();

        logger.info("itemRemoteService.listSpecialItemByIdList idList={}", ItemAdditionConst.ADDITION_FREE);
        ResponseDTO<List<ItemDRO>> itemResponseDTO = itemRemoteService.listSpecialItemByIdList(Lists.newArrayList(ItemAdditionConst.ADDITION_FREE));
        logger.info("itemRemoteService.listSpecialItemByIdList itemResponseDTO={}", itemResponseDTO);
        if (!itemResponseDTO.isSuccess()) {
            logger.error("#order#serviceitem 返修单服务项 categid ：{} ", ItemAdditionConst.ADDITION_FREE);
            return freeOrderServiceItemLists;
        }

        if (CollectionUtils.isEmpty(itemResponseDTO.getData())) {
            logger.error("#order#serviceitem 返修单服务项 categid ：{} ", ItemAdditionConst.ADDITION_FREE);
            return freeOrderServiceItemLists;
        }

        // 设置价格服务项
        ItemDRO freeServiceItemDRO = itemResponseDTO.getData().get(0);
        for (OrderProductExtend e : orderProductExtendList) {
            OrderServiceItem orderServiceItem = new OrderServiceItem();
            orderServiceItem.setOrderId(orderWork.getOrderId());
            orderServiceItem.setProExtId(e.getProExtId());
            orderServiceItem.setProductId(orderWork.getProductId());
            orderServiceItem.setProductName(Optional.ofNullable(e.getProductName()).orElse(e.getShowProductName()));
            orderServiceItem.setServItemId(freeServiceItemDRO.getItemId());
            orderServiceItem.setServItemName(freeServiceItemDRO.getItemName());
            orderServiceItem.setServItemCategId(freeServiceItemDRO.getItemTypeId());
            orderServiceItem.setServItemGroupId(freeServiceItemDRO.getItemTypeId());
            orderServiceItem.setServItemGroupName(freeServiceItemDRO.getItemTypeName());
            orderServiceItem.setNumber(1);
            orderServiceItem.setItemPrice(0);
            orderServiceItem.setTotalPrice(0);
            freeOrderServiceItemLists.add(orderServiceItem);
        }
        return freeOrderServiceItemLists;
    }

    /**
     * 创建一口价服务项
     *
     * @param orderWork
     * @param orderProductExtendList
     * @param finalPriceServiceItemDTO
     * @return
     * @throws OmsBaseException
     */
    private boolean createFinalPriceServiceItem(OrderWork orderWork, List<OrderProductExtend> orderProductExtendList,
                                                ServiceItemResultDTO finalPriceServiceItemDTO) throws OmsBaseException {
        for (OrderProductExtend e : orderProductExtendList) {
            // 处理内部结算价
            Integer internalPrice = Optional.ofNullable(finalPriceServiceItemDTO.getInternalSettlementPrice()).orElse(finalPriceServiceItemDTO.getPrice());
            Integer internalSettlementPrice = handleSettlementPrice(orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType(), internalPrice, finalPriceServiceItemDTO.getPrice());

            OrderServiceItem orderServiceItem = new OrderServiceItem();
            orderServiceItem.setOrderId(orderWork.getOrderId());
            orderServiceItem.setProExtId(e.getProExtId());
            orderServiceItem.setProductId(orderWork.getProductId());
            orderServiceItem.setProductName(Optional.ofNullable(e.getProductName()).orElse(e.getShowProductName()));
            orderServiceItem.setServItemId(finalPriceServiceItemDTO.getItemId());
            orderServiceItem.setServItemName(finalPriceServiceItemDTO.getItemName());
            orderServiceItem.setServItemGroupId(finalPriceServiceItemDTO.getItemCategId());
            orderServiceItem.setServItemGroupName(finalPriceServiceItemDTO.getItemCategName());
            orderServiceItem.setServItemCategId(finalPriceServiceItemDTO.getItemCategId());
            orderServiceItem.setNumber(1);
            orderServiceItem.setItemPrice(finalPriceServiceItemDTO.getPrice());
            orderServiceItem.setTotalPrice(finalPriceServiceItemDTO.getPrice());
            orderServiceItem.setExternalSettlementPrice(finalPriceServiceItemDTO.getExternalSettlementPrice());
            orderServiceItem.setExternalTotalPrice(finalPriceServiceItemDTO.getExternalSettlementPrice());
            orderServiceItem.setInternalSettlementPrice(internalSettlementPrice);
            orderServiceItem.setInternalTotalPrice(internalSettlementPrice);

            // 计价器订单-故障项明细
            if (Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_ORDER, orderWork.getServItemType())) {
                if (CollectionUtil.isNotNullOrEmpty(finalPriceServiceItemDTO.getDetailResultDTOList())) {
                    List<OrderServiceItemCell> itemCellList = new ArrayList<>(finalPriceServiceItemDTO.getDetailResultDTOList().size());
                    for (ServiceItemDetailResultDTO itemCell : finalPriceServiceItemDTO.getDetailResultDTOList()) {
                        OrderServiceItemCell cell = new OrderServiceItemCell();
                        cell.setItemCellId(itemCell.getItemCellId());
                        cell.setItemCellName(itemCell.getItemCellName());
                        cell.setCellPrice(itemCell.getCellPrice());
                        cell.setSort(itemCell.getSort());
                        itemCellList.add(cell);
                    }
                    orderServiceItem.setItemDetailList(itemCellList);
                }
            }

            AddOrderServiceItemDTO serviceItemDTO = new AddOrderServiceItemDTO();
            serviceItemDTO.setProExtId(e.getProExtId());
            serviceItemDTO.setOrderServiceItemList(Lists.newArrayList(orderServiceItem));
            serviceItemDTO.setOrderId(orderWork.getOrderId());
            serviceItemDTO.setWorkId(orderWork.getWorkId());

            // 保存服务项
            insertServiceItem(serviceItemDTO);
        }
        return true;
    }

    /**
     * 生成清洗默认服务项
     *
     * @return
     */
    private Integer getCleanOrderServiceItemOriginalAmount(OrderWork orderWork, OrderProduct orderProduct) {
        if (NumberUtil.isNullOrZero(orderWork.getProductId())) {
            return null;
        }

        List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(orderWork.getOrderId());

        ServiceItemQueryDTO serviceItemQueryDTO = ServiceItemQueryDTO
                .builder()
                .servItemType(orderWork.getServItemType())
                .productId(orderWork.getProductId())
                .cityId(orderWork.getCityId())
                .channelId(orderWork.getChannelId())
                .bizType(orderWork.getBizType())
                .tariffId(orderProducts.get(0).getTariffId())
                .general(GlobalConsts.YES)
                .build();
        ResponseDTO<ServiceItemResultDTO> responseDTO = servItemBService.getServiceItem(serviceItemQueryDTO);

        // 服务项数据为空
        if (!responseDTO.isSuccess() || Objects.isNull(responseDTO.getData())) {
            logger.error("#order#serviceitem orderId:{} 服务项为空 入参：{}", orderWork.getOrderId(), JSON.toJSONString(responseDTO));
            return null;
        }

        ServiceItemResultDTO defaultItem = responseDTO.getData();
        return defaultItem.getPrice() * orderProduct.getNumber();
    }

    /**
     * 创建天猫服务项
     * 服务项价格=渠道预付款
     *
     * @param orderWork
     * @param orderProduct
     * @throws OmsBaseException
     */
    private Integer getTmallInstallServiceItemOriginalAmount(OrderWork orderWork, OrderProduct orderProduct) {

        // 天猫默认服务项
        String serviceItemName = baseCodeService.getTmallServiceItemName(orderWork.getProductId());
        if (StringUtil.isBlank(serviceItemName)) {
            logger.error("#order#serviceitem#tmall 天猫服务项配置为空 orderId:{} productId：{}", orderWork.getOrderId(), orderWork.getProductId());
            return null;
        }

        List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(orderWork.getOrderId());

        ServiceItemQueryDTO serviceItemQueryDTO = ServiceItemQueryDTO
                .builder()
                .servItemType(orderWork.getServItemType())
                .channelId(orderWork.getChannelId())
                .bizType(orderWork.getBizType())
                .cityId(orderWork.getCityId())
                .productId(orderWork.getProductId())
                .tariffId(orderProducts.get(0).getTariffId())
                .build();
        List<ServiceItemResultDTO> serviceItemResultDTOList = servItemBService.listServiceItem(serviceItemQueryDTO);

        // 服务项数据为空
        if (CollectionUtils.isEmpty(serviceItemResultDTOList)) {
            logger.error("#order#serviceitem#tmall 服务项为空 orderId:{} 入参：{}", orderWork.getOrderId(), JSON.toJSONString(serviceItemResultDTOList));
            return null;
        }

        // 匹配服务项
        Optional<ServiceItemResultDTO> filterServiceItemOptional = serviceItemResultDTOList.stream().filter(e -> Objects.equals(serviceItemName, e.getItemName())).findFirst();
        if (!filterServiceItemOptional.isPresent()) {
            logger.error("#order#serviceitem#tmall 匹配服务项失败  serviceItemName:{} orderId:{}  ", serviceItemName, orderWork.getOrderId());
            return null;
        }

        ServiceItemResultDTO filterServiceItem = filterServiceItemOptional.get();
        return filterServiceItem.getPrice() * orderProduct.getNumber();
    }

    /**
     * 远程费服务项目原价
     *
     * @param orderWork
     * @param orderProduct
     */
    private Integer getRemoteAmountServiceItemOriginalAmount(OrderWork orderWork, OrderProduct orderProduct) {

        Long orderId = orderWork.getOrderId();

        // 厂商订单 不存在
        OrderFactory orderFactory = orderFactoryService.findOrderFactoryByKey(orderId);
        if (orderFactory == null) {
            logger.error("#order#serviceitem 厂商订单不存在 订单号：{}", orderId);
            return null;
        }

        Integer cleanAmount = getCleanOrderServiceItemOriginalAmount(orderWork, orderProduct);
        if (cleanAmount == null) {
            return null;
        }

        // 远程费为空
        Integer remoteAmount = orderFactory.getRemoteAmount();
        if (remoteAmount == null) {
            return cleanAmount;
        }

        return cleanAmount + remoteAmount;
    }

    /**
     * 获取远程费服务项目
     *
     * @param orderWork   订单id
     * @param amount      远程费
     * @param proExtId    产品扩展id
     * @param productId   产品Id
     * @param productName 产品名称
     * @return
     */
    private OrderServiceItem getRemoteAmountServiceItem(OrderWork orderWork, Integer amount, Long proExtId, Integer productId, String productName) {

        ResponseDTO<List<ItemDRO>> itemResponseDTO = itemRemoteService.listSpecialItemByIdList(Lists.newArrayList(ItemAdditionConst.ADDITION_REMOTE));
        if (!itemResponseDTO.isSuccess()) {
            logger.error("#order#serviceitem 获取远程费服务项为空 categid ：{} ", ItemAdditionConst.ADDITION_REMOTE);
            return null;
        }

        if (CollectionUtils.isEmpty(itemResponseDTO.getData())) {
            logger.error("#order#serviceitem 获取远程费服务项为空 categid ：{} ", ItemAdditionConst.ADDITION_REMOTE);
            return null;
        }

        ItemDRO servServiceItemDRO = itemResponseDTO.getData().get(0);

        // 处理内部结算价
        Integer internalPrice = Optional.ofNullable(servServiceItemDRO.getPriceInternalSettlement()).orElse(servServiceItemDRO.getPrice());
        Integer internalSettlementPrice = handleSettlementPrice(orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getBizType(), internalPrice, amount);

        OrderServiceItem orderServiceItem = new OrderServiceItem();
        orderServiceItem.setProExtId(proExtId);
        orderServiceItem.setOrderId(orderWork.getOrderId());
        orderServiceItem.setProductId(productId);
        orderServiceItem.setProductName(productName);
        orderServiceItem.setItemPrice(amount);
        orderServiceItem.setNumber(1);
        orderServiceItem.setTotalPrice(amount);
        orderServiceItem.setServItemId(servServiceItemDRO.getItemId());
        orderServiceItem.setServItemName(servServiceItemDRO.getItemName());
        orderServiceItem.setServItemGroupId(servServiceItemDRO.getItemTypeId());
        orderServiceItem.setServItemGroupName(servServiceItemDRO.getItemTypeName());
        orderServiceItem.setServItemCategId(servServiceItemDRO.getItemTypeId());
        orderServiceItem.setExternalSettlementPrice(servServiceItemDRO.getPriceExternalSettlement());
        orderServiceItem.setExternalTotalPrice(servServiceItemDRO.getPriceExternalSettlement());
        orderServiceItem.setInternalSettlementPrice(internalSettlementPrice);
        orderServiceItem.setInternalTotalPrice(internalSettlementPrice);

        return orderServiceItem;
    }

}
